#include "EleScence.h"
#include <cmath>
#include <QtMath>
#include <QGuiApplication>
#include <QResizeEvent>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QPaintEvent>
#include <QPainter>
#include <QPainterPath>
#include <vector>
#include <QLabel>
#include <Calculate.h>

EleScence::EleScence(QWidget *parent) : QWidget(parent)
{
    LineUp = true;
    isMoving = false;
    isDraw = false;
    dt = 0;

    //得到电场场景的配置参数;

    //初始默认值
    vs = 3 * pow(10, 7);      //速度大小3*10^7
    vd = 0;                   //速度方向水平向右
    cmr = 1.758 * pow(10, 11);
    isPost = false;           //负电
    e = 10000;                //电场强度V/m
    isUp = true;              //电场线向上
    times = 0;                //初始化次数为0

    //算轨迹上的所有点
    calcPoints(-70, 0, -70, 70, -70, 70);


}
void EleScence::paintEvent(QPaintEvent *event)
{

    event->accept();
    QPainter painter(this);

    //设置抗锯齿
    painter.setRenderHint(QPainter::Antialiasing);

    //设置窗口
    mySetWindow(painter, 100, 100, 200, 200);

    //绘图
    myDraw(painter);

    //绘制粒子
    myDrawPath(painter, -70, 70, -70, 70);
    //绘制粒子轨迹
    if (times >= 2) {
        for (int i = 2; i < times; ++i) {
            painter.drawPoint(data[i - 2]);
        }
    }
    this->isDraw = false;
}


void EleScence::myDraw(QPainter &painter)
{

    //画场景标题
    QFont font;
    font.setFamily("隶书");
    font.setPointSize(8);
    font.setPixelSize(12);
    painter.setFont(font);
    painter.setPen(QColor(235,51,36));
    if (!isMoving) {
        painter.drawText(QRectF(-80,-110,160,40),Qt::AlignCenter, "粒子在电场中的运动");
    }
    QPen pen;
    //画坐标轴
    if (true) {
        pen.setWidth(0);
        pen.setStyle(Qt::SolidLine);
        QColor color;
        color.setAlpha(50); //设置背景透明度
        pen.setColor(color);
        painter.setPen(pen);
        int x1 = 0;
        int x2 = 0;
        int y1 = 68;
        int y2 = -68;
        painter.drawLine(x1, y1, x2, y2);//箭身
        double arrowEndX1, arrowEndY1;//箭头端点1
        double arrowEndX2, arrowEndY2;//箭头端点2
        double arrowLength = 5;       // 箭头长度
        arrowEndX1 = x2 - arrowLength * 0.5;
        arrowEndY1 = y2 + arrowLength * sqrt(3)/2;
        arrowEndX2 = x2 + arrowLength * 0.5;
        arrowEndY2 = y2 + arrowLength * sqrt(3)/2;
        painter.drawLine(x2, y2, arrowEndX1, arrowEndY1);//画箭头的第一个角
        painter.drawLine(x2, y2, arrowEndX2, arrowEndY2);//画箭头的第二个角
        QFont font;
        font.setPointSize(1);
        font.setPixelSize(5);
        painter.setFont(font);
        painter.drawText(QRectF(4, -70, 10, 10),Qt::AlignLeft, "y");
        x1 = -70;
        x2 = 70;
        y1 = 0;
        y2 = 0;
        painter.drawLine(x1, y1, x2, y2);//箭身
        arrowEndX1 = x2 - arrowLength * sqrt(3)/2;
        arrowEndY1 = y2 + arrowLength * 0.5;
        arrowEndX2 = x2 - arrowLength * sqrt(3)/2;
        arrowEndY2 = y2 - arrowLength * 0.5;
        painter.drawLine(x2, y2, arrowEndX1, arrowEndY1);//画箭头的第一个角
        painter.drawLine(x2, y2, arrowEndX2, arrowEndY2);//画箭头的第二个角
        painter.drawText(QRectF(70, 2, 10, 10),Qt::AlignLeft, "x");
    }


    //画电极板(边界线)
    QPoint baseTopPointBegin = {-70, 70};
    QPoint baseTopPointEnd = {70, 70};
    QPoint baseBottomPointBegin = {-70, -70};
    QPoint baseBottomPointEnd = {70, -70};

    pen.setColor(QColor(0, 0, 0));
    painter.setPen(pen);

    painter.drawLine(baseTopPointBegin, baseTopPointEnd);
    painter.drawLine(baseBottomPointBegin, baseBottomPointEnd);

    if (LineUp) {
        for (int i = 0; i + -60 < 70; i += 20) {//循环画向上的电场线
            drawArrow(-60 + i, 60, -60 + i, -60, painter);
        }
    } else {
        for (int i = 0; i + -60 < 70; i += 20) {//循环画向下的电场线
            drawArrow(-60 + i, -60, -60 + i, 60, painter);
        }
    }

}

void EleScence::drawArrow(double x1, double y1, double x2, double y2, QPainter &painter)
{
    /*
     * 画一个箭头
     */
    if (LineUp) {//如果是向上画箭头，即电场方向朝上
        if (!isMoving) {
            //设置画笔
            QPen pen;
            pen.setWidthF(0.6);
            QColor color;

            pen.setColor(color);
            //箭身
            painter.setPen(pen);
            painter.drawLine(x1, y1, x2, y2);
            //箭头
            double arrowEndX1, arrowEndY1;//箭头端点1
            double arrowEndX2, arrowEndY2;//箭头端点2
            double arrowLength = 8;       // 箭头长度

            // 求得箭头点 1 的坐标
            arrowEndX1 = x2 - arrowLength * 0.5;
            arrowEndY1 = y2 + arrowLength * sqrt(3)/2;

            // 求得箭头点 2 的坐标
            arrowEndX2 = x2 + arrowLength * 0.5;
            arrowEndY2 = y2 + arrowLength * sqrt(3)/2;

            painter.drawLine(x2, y2, arrowEndX1, arrowEndY1);//画箭头的第一个角
            painter.drawLine(x2, y2, arrowEndX2, arrowEndY2);//画箭头的第二个角
        } else {//如果例子运动则标明电极板
            //画正
            QPen pen;
            pen.setWidthF(0.6);
            painter.setPen(pen);
            x1 += 5;
            painter.drawLine(x1 - 5, y1 + 20, x1 - 5, y1 + 14);//竖
            painter.drawLine(x1 - 8, y1 + 17, x1 - 2, y1 + 17);//横
            //画负
            painter.drawLine(x1 - 8, y2 - 17, x1 - 2, y2 - 17);//横
        }
    } else {//电场方向朝下
        if (!isMoving) {
            //设置画笔
            QPen pen;
            pen.setWidthF(0.6);
            QColor color;
//            color.setAlpha(30); //设置画笔透明度
            pen.setColor(color);
            //箭身
            painter.setPen(pen);
            painter.drawLine(x1, y1, x2, y2);
            //箭头
            double arrowEndX1, arrowEndY1;//箭头端点1
            double arrowEndX2, arrowEndY2;//箭头端点2
            double arrowLength = 8;      // 箭头长度

            // 求得箭头点 1 的坐标
            arrowEndX1 = x2 - arrowLength * 0.5;
            arrowEndY1 = y2 - arrowLength * sqrt(3)/2;

            // 求得箭头点 2 的坐标
            arrowEndX2 = x2 + arrowLength * 0.5;
            arrowEndY2 = y2 - arrowLength * sqrt(3)/2;

            painter.drawLine(x2, y2, arrowEndX1, arrowEndY1);//画箭头的第一个角
            painter.drawLine(x2, y2, arrowEndX2, arrowEndY2);//画箭头的第二个角
        } else {//如果例子运动则标明电极板
            //画正
            QPen pen;
            pen.setWidthF(0.6);
            painter.setPen(pen);
            x1 += 5;
            painter.drawLine(x1 - 5, y1 - 20, x1 - 5, y1 - 14);//竖
            painter.drawLine(x1 - 8, y1 - 17, x1 - 2, y1 - 17);//横
            //画负
            painter.drawLine(x1 - 8, y2 + 17, x1 - 2, y2 + 17);//横
        }
    }


}

void EleScence::myDrawPath(QPainter &painter, qreal top, qreal bottom, qreal left, qreal right)
{
    if (this->isDraw) {
        if (this->isPost) {//如果是正电小球
            if (times < data.size() &&  data[times].x() >= left && data[times].x() <= right
                    && data[times].y() <= bottom && data[times].y() >= top) {
                painter.drawLine(QPointF(data[times].x() - 1, data[times].y()), QPointF(data[times].x() + 1, data[times].y()));
                painter.drawLine(QPointF(data[times].x(), data[times].y() + 1), QPointF(data[times].x(), data[times].y() - 1));
                painter.drawEllipse(data[times], 2, 2);
                times++;
            } else {
                isRepaint = true;
                times = 0;
                isDraw = false;
            }
        } else {//如果是负电小球
            if (times < data.size() &&  data[times].x() >= left && data[times].x() <= right
                    && data[times].y() <= bottom && data[times].y() >= top) {
                painter.drawLine(QPointF(data[times].x() - 1, data[times].y()), QPointF(data[times].x() + 1, data[times].y()));
                painter.drawEllipse(data[times], 2, 2);
                times++;
            } else {
                isRepaint = true;
                times = 0;
                isDraw = false;
            }
        }
    } else {
        if (times >= 1) {//如果粒子已经在运动,该if分支防止暂停时，拖拉窗口重绘导致的小球消失问题
            if (this->isPost) {//如果是正电小球
                if (times - 1 < data.size() &&  data[times - 1].x() >= left && data[times - 1].x() <= right
                        && data[times - 1].y() <= bottom && data[times - 1].y() >= top) {
                    painter.drawLine(QPointF(data[times - 1].x() - 1, data[times - 1].y()), QPointF(data[times -1].x() + 1, data[times - 1].y()));
                    painter.drawLine(QPointF(data[times - 1].x(), data[times - 1].y() + 1), QPointF(data[times - 1].x(), data[times - 1].y() - 1));
                    painter.drawEllipse(data[times - 1], 2, 2);
                    this->isDraw = false;
                } else {
                    times = 0;
                    isDraw = false;
                }
            } else {//如果是负电小球
                if (times - 1 < data.size() &&  data[times - 1].x() >= left && data[times - 1].x() <= right
                        && data[times - 1].y() <= bottom && data[times - 1].y() >= top) {
                    painter.drawLine(QPointF(data[times - 1].x() - 1, data[times - 1].y()), QPointF(data[times - 1].x() + 1, data[times - 1].y()));
                    painter.drawEllipse(data[times - 1], 2, 2);
                    this->isDraw = false;
                } else {
                    times = 0;
                    isDraw = false;
                }
            }
        } else {//该else分支用来画初始位置小球
            if (this->isPost) {//如果是正电小球
                painter.drawLine(QPointF(data[0].x() - 1, data[0].y()), QPointF(data[0].x() + 1, data[0].y()));
                painter.drawLine(QPointF(data[0].x(), data[0].y() + 1), QPointF(data[0].x(), data[0].y() - 1));
                painter.drawEllipse(data[0], 2, 2);
                isDraw = false;
            } else {//如果是负电小球
                painter.drawLine(QPointF(data[0].x() - 1, data[0].y()), QPointF(data[0].x() + 1, data[0].y()));
                painter.drawEllipse(data[0], 2, 2);
                isDraw = false;
            }
        }
    }

}
void EleScence::calcPoints(qreal startX, qreal startY, qreal top, qreal bottom, qreal left, qreal right)
{
    /* *
     *  double vs;
     *  double vd;
     *  double q;
     *  double isPost;
     *  double e;
     *  double isUp;
     *
     * */

    QPointF begin = {startX, startY};
    data.push_back(begin);
    QPointF particle = begin;

    while (particle.x() >= left && particle.x() <= right && particle.y() <= bottom && particle.y() >= top) {
        dt += 1;
        particle.setX(begin.x() + pow(10, 2.35) * inEleCalX(pow(10, -9.55) * dt, this->vs, this->vd));
        particle.setY(- pow(10, 2.25) * inEleCalY(pow(10, -9.55) * dt, this->vs, this->vd, this->cmr, this->isPost, this->e, this->isUp));
        data.push_back(particle);
    }
}
void EleScence::mySetWindow(QPainter &painter, int x, int y, int w, int h)
{
    int W=width();
    int H=height();

    //取长和宽的小值
    int side=qMin(W,H);

    //viewport矩形区
    QRect rect((W-side)/2, (H-side)/2,side,side);

    //设置Viewport
    painter.setViewport(rect);

    //设置窗口大小，逻辑坐标
    painter.setWindow(-x, -y, w, h);

}

